#include<filesystem>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Teacher
{
	int num;
	int sex;
	char name[20];
	int year;
	Teacher *next;
}*teacher;
int n;	//n存着信息条数
teacher phead=NULL;//phead为链表首地址
void Create()          //建立链表
{
    teacher pend,pnew;//尾节点，新节点
    pend=phead =(teacher)malloc(sizeof(struct Teacher));//分配内存给首节点
    printf("please first input Num, Name, Sex and year:\n");
    for(int i=0;i<n;i++)
    {
        pnew=(teacher)malloc(sizeof(struct Teacher));  //分配新节点
        pend->next=pnew;   //原来的尾节点指向新节点
        pnew->next=NULL;  	//新节点的指针为NULL
        printf("NO.%d: ",i+1);
        scanf("%d", &pend->num);
		getchar();
        scanf("%s",&pend->name);
        scanf("%d", &pend->sex);
		scanf("%d",&pend->year);
        pend=pnew;  //赋值后指向尾节点
    }
    pnew=pnew->next;//指向NULL
    free(pnew);      //释放pnew内存
}
void save(char *filename)
{
    FILE *w;//文件指针
	//打开文件的方式: r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b 默认使用的是r(只读)模式
    if ((w = fopen(filename, "wb")) == NULL){   /*二进制只写打开文件,a+模式如果不存在文件会自动创建(append，自动追加)*/
        printf("cannot open file\n");
        exit(1);
    }
    for (int i = 0; i < n; i++)  //链表数据循环输入到文件内
    {
		fprintf(w,"%d ",phead->num);
		fprintf(w,"%s ",phead->name);
		fprintf(w,"%d ",phead->sex);
		fprintf(w,"%d", phead->year);
		fprintf(w,"%s","\r\n");//换行
		phead=phead->next;//指向下一个节点
    }
    fclose(w);	//关闭文件
}

void insert(teacher *head)//插入
{
	teacher p=(teacher)malloc(sizeof(struct Teacher));
	scanf("%d %s %d %d",&p->num,&p->name,&p->sex,&p->year);
	teacher q=(*head)->next;
	while(q->next->num<p->num&&q->next!=NULL)  //找到位置插到q后面
	{
		q=q->next;
	}
	p->next=q->next;
	q->next=p;
}
void build(teacher &head)//从文件中读数据并建立链表，改了传入的指针所以传指针的引用
{
	if(head==NULL){
		head=(teacher)malloc(sizeof(struct Teacher));
		head->next=NULL;
	}
	FILE *fp=fopen("./teacher.txt","rb");//二进制只读
	if(fp==NULL)
		printf("FILE OPEN ERROR\n");
	teacher q=head;
	char line[1024];
    void* ret;//这里注意类型
	while(true)
	{
		// rewind(fp);//光标回跳到文件开头
		memset(line, 0, sizeof(line));
		ret = fgets(line, sizeof(line), fp);
		if(ret==NULL)	break;
		// if(line[strlen(line)-1]=='\n' || line[strlen(line)-1]=='\r') {
        //     line[strlen(line) - 1] = '\0';
        // }
        // if(line[strlen(line)-1]=='\r' || line[strlen(line)-1]=='\n') {
        //     line[strlen(line) - 1] = '\0';
        // }
		teacher p=(teacher)malloc(sizeof(struct Teacher));
		sscanf(line,"%d %s %d %d",&p->num,p->name,&p->sex,&p->year);//读取失败返回EOF，成功返回赋值成功的个数
		p->next=head->next;
		head->next=p;
	}
	fclose(fp);
}

void build(teacher &head){
	if(head==NULL){
		head=(teacher)malloc(sizeof(struct Teacher));
		head->next=NULL;
	}
	FILE *fp=fopen("./xx.txt","rb");
	if(fp==NULL){
		printf("打开文件失败！");
		exit(0);
	}
	char line[1024];
	void *ret;
	while(true){
		memset(line,0,sizeof(line));
		ret=fgets(line,sizeof(line),fp);
		if(ret==NULL) break;
		if(line[strlen(line)-1]=='\n' || line[strlen(line)-1]=='\r')
			line[strlen(line)-1]='\0';
		teacher t=(teacher)malloc(sizeof(struct Teacher));
		sscanf("%d %s %d %d",&t->num,t->name,&t->sex,&t->year);
		t->next=head->next;
		head->next=t;
	}
	fclose(fp);
}
void sort(teacher head)//只改数据不需要传引用
{
	teacher p,pre,tail;//冒泡排序
	tail=NULL;
	while(head->next!=tail)//当已经有序的最后一个结点是head->next就排完序了
	{
	   pre=head;
	   p=head->next;
	   while(p->next!=tail)//如果p->next没有到tail说明这一趟排序还没有选出最大元素
	   {
		   if(p->num>p->next->num)//当前节点比后面的节点大，换位置
		   {	
			   pre->next=p->next;
			   p->next=pre->next->next;
			   pre->next->next=p;
		   }
		   else
		   {   
			   p=p->next;
		   }
		   pre=pre->next;
	   }
	   tail=p;//更新表尾节点，已经有序的最后一个结点
	}
}
void del(teacher head)
{
	int n;
	scanf("%d",&n);//读入要删除的结点序号
	teacher p=head;
	while(p!=NULL&&p->next!=NULL)
	{
		//p!=NULL是因为删除了p的后继之后，p可能为尾结点，这时P后移就会遇到NULL
		if(p->next->num==n)
		{
			teacher temp=p->next;
			p->next=p->next->next;
			free(temp);
			return;
		}
		p=p->next;
	}
	return;
}
void show(char *filename)/*输出文件*/
{
    FILE *fp;//文件指针
    struct Teacher info[100];  //负责存放文件中的数据，然后输出
    if ((fp = fopen(filename, "rb")) == NULL){   /*二进制只读打开文件*/
        printf("cannot open file\n");
        exit(1);
    }
    for (int i = 0; i < n; i++)
    {
		fscanf(fp,"%d",&(info[i].num));//输出数据到数组
        fscanf(fp,"%s",&(info[i].name));
        fscanf(fp,"%d",&(info[i].sex));
        fscanf(fp,"%d",&(info[i].year));
        printf("%d\t%s\t%d\t%d\n", info[i].num, 
        	info[i].name, info[i].sex, info[i].year);//输出数据到屏幕
    }
    fclose(fp);/*关闭文件*/
}
void printTeacherList(teacher head){
	teacher p=head->next;
	while(p){
		printf("%d %s %d %d\n",p->num,p->name,p->sex,p->year);
		p=p->next;
	}
}
int main(){
	char filename[50];
    // printf("How many ?:\n");
    // scanf("%d", &n);		/*输入老师数*/
    // printf("please input filename: ");
    // scanf("%s", filename); /*输入文件所在路径及名称*/
    // Create();       //调用函数建立链表
    // save(filename); //调用函数存到文件
    // free(phead);//释放phead内存
	// show(filename); //调用函数输出文件
	teacher t=NULL;
	build(t);
	sort(t);
	del(t);
	printTeacherList(t);
	// insert(&t);
	return 0;
}